#|___________________________________________________________________ 
 | 
 | ViSta - The Visual Statistics System
 | Copyright (c) 1991-2000 by Forrest W. Young
 | For further information contact the author 
 | forrest@unc.edu or http://forrest.psych.unc.edu
 |
 | This file contains I/O functions for preference files
 | DESKTOP.LSP WORKMAP.LSP
 | Methods for PREFS.LSP are in systmob2.lsp
 |___________________________________________________________________ 
 |#


(defun probe-base-file ()
(when *v* (format t "; probing for base directory~%"))
(if *base-dir-name*
      (open (strcat *base-dir-name* "dataobj1.lsp") 
            :direction :probe :if-does-not-exist nil)
      nil))

#|
(defun probe-file (file )
  (cond
    ((with-open-file (stream file :direction :probe :if-does-not-exist nil))	
     (truename file))
    ((with-open-file (stream (merge-pathnames file ".fsl")
         :direction :probe :if-does-not-exist nil))
     (truename (merge-pathnames file ".fsl")))
    ((with-open-file (stream (merge-pathnames file ".lsp")
         :direction :probe :if-does-not-exist nil))
     (truename (merge-pathnames file ".lsp")))))
|#

(defun update-pref-files (&optional make-distribution gui)
"Args &optional make-distribution gui
Saves all configuration files in prefs directory except workmap and desktop. Configuration is for distribution only if make-distribution is T. Also saves workmap and desktop configuration files if gui is T."
  (when *file-verbose* (format t "; saving preference files~%"))  
  (cond ;done by prefoad 
    (*vista* (send *vista* :save-prefs make-distribution))
    (t (when *file-verbose* 
             (format t "; prefs\\prefs.lsp    not saved - *vista* system object does not exist~%")))))

(defun update-gui-files (&optional make-distribution)
"Updates the workmap and desktop configuration files in the prefs directory"
  (cond (*vista* (save-workmap-settings make-distribution))
    (t (when *file-verbose* 
             (format t "; prefs\\workmap.lsp  not saved - *vista* system object does not exist~%"))))
  (cond (*vista* (save-desktop-settings t))
    (t (when *file-verbose* 
             (format t "; prefs\\desktop.lsp  not saved - *vista* system object does not exist~%"))))
  (write-prefload-file make-distribution)
  (write-verbose-file make-distribution)
  t)


(defun save-prefs (&optional make-distribution) 
  (update-pref-files make-distribution))

(defun save-all-prefs (&optional make-distribution)
  (update-pref-files make-distribution))

(defun save-the-environment () (save-environment))

(defun save-environment ()
"Args: none
Updates all files in prefs directory except initial.lsp and the -bak.lsp files.
Then copies the entire prefs directory to genesys directory"
  (save-every-pref-file nil nil)
  (backup-directory *prefs-path* *genesys-path*)
  )

(defun backup-directory (in-dir backup-dir)
"Args: IN-DIR BACKUP-DIR
Arguments may be either path or directory strings. Checks to see if both in-dir and backup-dir exist. If both do, copies all .lsp files in in-dir to backup-dir, overwriting files by the same name."
  (let* ((cur-dir (get-working-directory)))
    (cond
      ((and (set-working-directory backup-dir)
            (set-working-directory in-dir))
       (mapcar #'(lambda (file)
                   (copy-file file (strcat backup-dir *separator* file)))
               (mapcar #'file-namestring (directory (strcat in-dir *separator* "*.lsp"))))
       (set-working-directory cur-dir)
       t)
      (t
       (set-working-directory cur-dir)
       (error "bad directories")
       nil))))
    
       
(defun save-every-pref-file (&optional make-distribution (verbose nil))
"Args: &optional make-distribution (verbose *file-verbose*)
Updates all files in prefs directory except initial.lsp and the -bak.lsp files. Uses current settings unless MAKE-DISTRIBUTION is T, in which case uses distribution defaults. Prints *file-verbose* message when VERBOSE is T."
  (cond 
    (verbose (save-every-pref-filev make-distribution t))
    (t
     (if *workmap* (save-workmap-settings nil "wrkmpgui.lsp"))
     (when *vista* 
           (save-desktop-settings t   "dsktpgui.lsp")
           (save-plugin-settings  nil "plgingui.lsp")
           (save-workmap-settings make-distribution)
           (save-desktop-settings t)
           (send *vista* :save-prefs))
     (write-verbose-file make-distribution))))

(defun save-every-pref-filev (&optional make-distribution (verbose nil))
"Args: &optional make-distribution (verbose *file-verbose*)
Updates all files in prefs directory except initial.lsp and the -bak.lsp files. Uses current settings unless MAKE-DISTRIBUTION is T, in which case uses distribution defaults. Prints *file-verbose* message when VERBOSE is T."
  (let* ((verb *file-verbose*))
    (setf *file-verbose* verbose)
    (if *workmap* 
       (save-workmap-settings nil "wrkmpgui.lsp")
        (when *file-verbose* 
              (format t "; prefs\\wrkmpgui.lsp not saved - no *workmap* object~%")))
    (cond 
      (*vista* 
       (save-desktop-settings t   "dsktpgui.lsp")
       (save-plugin-settings  nil "plgingui.lsp")
       (save-workmap-settings make-distribution)
       (save-desktop-settings t)
       (send *vista* :save-prefs)
       )
      (*file-verbose* 
       (format t "; prefs\\plgingui.lsp not saved - no *vista*   object~%")
       (format t "; prefs\\dsktpgui.lsp not saved - no *vista*   object~%")
       (format t "; prefs\\desktop.lsp  not saved - no *vista*   object~%")
       (format t "; prefs\\workmap.lsp  not saved - no *vista*   object~%")))
    (write-verbose-file make-distribution)
    (setf *file-verbose* verb)))


(defun write-prefs (&optional make-distribution) 
  (update-pref-files make-distribution))

(defun write-all-prefs (&optional make-distribution) 
  (update-pref-files make-distribution))

(defun file-to-file (infile outfile) (copy-file infile outfile))

(defun copy-file (infile outfile)
"Args: INFILE OUTFILE
Copies infile to outfile. may not work for non-ascii (text) files"
    (with-open-file (in infile :direction :input)
                    (with-open-file (out outfile :direction :output)
                                    (let* ((line))
                                      (loop 
                                       (setf line (read-line in nil "*eof*"))
                                       (when (equal line "*eof*") (return))
                                       (format out "~a~%" line))))))

(setf *workmap* nil)

(defun localize-seven-values ()
    (use-seven-values (apply #'set-seven-values (default-seven-values)))
     (with-open-file (file (strcat *prefs-path* "seven.lsp") :direction :output)
                     (print `(setf *seven-values* ',(get-seven-values)) file)
         (print `(setf *default-seven-values* ',*default-seven-values*) file)))


(defun update-seven-values ()
  (apply #'set-seven-values (get-seven-values)))

(defun save-seven-values ()
  (update-seven-values)
  (with-open-file (file (strcat *prefs-path* "seven.lsp") :direction :output)
                  (print `(setf *seven-values* ',(get-seven-values)) file)))

(defun load-seven-values ()
  (load (strcat *prefs-path* "seven.lsp") ))

(defun initialize-seven-values ()
  (load-seven-values)
  (apply #'set-seven-values *seven-values*)
  (use-seven-values)
  )

(defun get-seven-values ()
"Args: none
Returns list of the seven current values for desktop and spreadplot layout: The values are the desktop's width and height, the x and y position of its upper-left corner, proportion of desktop height that is WorkMap (now always 1, since datasheet is invisible); and the maximum width and height for spreadplots. Use the (set-seven-values) and (use-seven-values) functions to return to the current layout later."
  (combine (send *desktop-container* :size) (send *desktop-container* :location) (send *vista* :workmap-proportion) (send *vista* :spreadplot-sizes)))

; 3760411
; 3768902
         

(defun default-seven-values ()
"Args: none
Returns list of seven default values for desktop and spreadplot layout: Width, Height, X-position of upper-left corner, Y-position of upper-left corner, proportion of height that is WorkMap (now always 1, since datasheet is invisible); maximum spreadplot width, maximum spreadplot height"
    (let* ((ss (effective-screen-size))
           (w (- (first ss) 60))
           (h (- (second ss) 60))
           (x (+  0 (floor (/ (-  (first  ss) w) 2))));10
           (y (+ 20 (floor (/ (-  (second ss) h) 2))));34
           (h (- h 20))
           (p 1)
           (sw (first ss))
           (sh (second ss)))
      (list w h x y p sw sh)))

(defun set-default-seven-values ()
  (setf *default-seven-values* (default-seven-values)))

(set-default-seven-values)

(defun seven-values () 
"Args: none
Returns list of seven current values for desktop and spreadplot layout as stored in *vista* slots. Values are Width, Height, X-position of upper-left corner, Y-position of upper-left corner, proportion of height that is WorkMap (now always 1, since datasheet is invisible); maximum spreadplot width, maximum spreadplot height"
(seven-desktop-values))


(defun seven-desktop-values ()
  (let* ((seven-values
          (combine (send *vista* :desktop-size)
                   (send *vista* :desktop-location)
                   (send *vista* :workmap-proportion)
                   (send *vista* :spreadplot-sizes)))
         )
    (setf *seven-values* seven-values)))



(defun save-seven-desktop-values ()
  (let* ((seven-values
          (combine (if (send *workmap* :showing)
                       (send *desktop-container* :size)
                       (send *vista* :desktop-size))
                   (if (send *workmap* :showing)
                       (send *desktop-container* :location)
                       (send *vista* :location))
                   (send *vista* :workmap-proportion)
                   (if (< (min (send *vista* :spreadplot-sizes)) 0)
                       (select *default-seven-values* '(5 6))
                       (send *vista* :spreadplot-sizes)))))
    (setf *seven-values* seven-values)))


(defun set-seven-values (w h x y p sw sh)
"Args: desktop width, desktop height, desktop x-position, desktop y-position, proportion of desktop that is workmap (relative to datasheet), maximum spreadplot width, and maximum spreadplot height
Sets values for the list of seven values for desktop and spreadplot layout without modifying layout. The values are stored in slots of the *vista* system object. The slots are DESKTOP-SIZE, DESKTOP-LOCATION, WORKMAP-PROPORTON and SPREADPLOT-SIZES. To apply the new values, use the (use-seven-values) function."
   (send *vista* :desktop-size (list w h))
   (send *vista* :desktop-location (list x y))
   (send *vista* :workmap-proportion p)
   (send *vista* :spreadplot-sizes (list sw sh))
   (seven-values)
   )

(defun repair-seven-values ()
    (let* ((7v (set-default-seven-values)))
      (apply #'set-seven-values 7v)
      (use-seven-values)))


(defun use-seven-values (&optional (values *seven-values*))
"Args: none
Applies list of seven values for desktop and spreadplot layout: Width, Height, X-position of upper-left corner, Y-position of upper-left corner, proportion of height that is WorkMap (now always 1, since datasheet is invisible); maximum spreadplot width, maximum spreadplot height"
  (send *vista* :desktop-size (select values (list 0 1)))
  (send *vista* :workmap-proportion (select values 4))
  (send *vista* :spreadplot-sizes (select values (list 5 6)))
  (send *vista* :desktop-location (select values (list 2 3)))
  (send *vista* :desktop-size (select values '(0 1)))
  (apply #'send *desktop-container* :location (select values (list 2 3)))
  (apply #'send *desktop-container* :size     (select values (list 0 1)))
  values 
  )


(defun load-gui (&key (use-backup nil))
"Args: &key (use-backup nil)
Loads all the code needed to reconstruct the DeskTop/WorkMap gui. Loaded from files dsktpgui.lsp, wrkmpgui.lsp and plgingui.lsp unless usebackup is T, in which case loaded from files dsktpgui-bak.lsp, wrkmpgui-bak.lsp and plgingui-bak.lsp "
  (cond
    (use-backup
     (failsafe-load *PREFS-PATH* "plgingui-bak.lsp")
     (failsafe-load *PREFS-PATH* "dsktpgui-bak.lsp")
     (failsafe-load *PREFS-PATH* "wrkmpgui-bak.lsp"))
    (t
     (failsafe-load *PREFS-PATH* "plgingui.lsp")
     (failsafe-load *PREFS-PATH* "dsktpgui.lsp")
     (failsafe-load *PREFS-PATH* "wrkmpgui.lsp"))
    )
  (seven-desktop-values)
  )

(defun load-plugin-settings ()
"Args: none
Loads all the code needed to reconstruct the plugin gui. Loaded from file plgingui.lsp"
  (failsafe-load *prefs-dir-name* "plgingui.lsp")
  )

(defun save-gui ()
"Args: none
Saves all the code needed to reconstruct the DeskTop/WorkMap gui. Saved in three files, dsktpgui.lsp, wrkmpgui.lsp and plgingui.lsp."
  (cond  
    (*workmap* 
     (save-workmap-settings nil "wrkmpgui.lsp")
     (when *file-verbose* (format t "; workmap settings preserved in wrkmpgui.lsp~%"))) 
    (*file-verbose* 
     (format t "; prefs\\wrkmpgui.lsp not saved - *workmap* does not exist~%")))
  (cond 
    (*vista* 
     (save-desktop-settings t "dsktpgui.lsp")
     (when *file-verbose* (format t "; desktop settings preserved in dsktpgui.lsp~%"))
     (save-plugin-settings nil "plgingui.lsp")
     (when *file-verbose* (format t "; plugin  settings preserved in plgingui.lsp~%")))
    (*file-verbose* 
     (format t "; prefs\\dsktpgui.lsp not saved - *vista* system object does not exist~%")
     (format t "; prefs\\plgingui.lsp not saved - *vista* system object does not exist~%")))
  )

(defun save-plugin-settings (&optional make-distribution filename)
  (unless filename (setf filename "plgingui.lsp"))
  (let ((oldbreak *breakenable*)
        (file (open (strcat *prefs-dir-name* filename) :direction :output)))
    (setq *breakenable* nil)
    (unwind-protect
     (cond 
       (make-distribution
        (print `(send *toolbar* :enable-soft-buttons nil) file)
        (print `(send *toolbar* :soft-button-titles ',*initial-button-names*) file)
        (print `(send *vista*   :previous-plugins ',*initial-button-names*) file)
        (print `(send *vista*   :analysis-menu-item-titles ',*initial-analysis-menu-items*) file)
        (print `(send *workmap* :num-toolbar-buts ,*initial-nmobs* ) file)
        (print `(setf *num-toolbar-buts-shown-at-startup*  ,*initial-nmobs* ) file)
        )
       (t
        (print `(send *toolbar* :enable-soft-buttons ,(send *toolbar* :enable-soft-buttons)) file)
        (print `(send *toolbar* :soft-button-titles ',(send *toolbar* :soft-button-titles)) file)
        (print `(send *vista*   :previous-plugins ',(send *vista* :previous-plugins)) file)
        (print `(send *vista*   :analysis-menu-item-titles ',(send *vista* :analysis-menu-item-titles)) file)
        (print `(send *workmap* :num-toolbar-buts ,(send *workmap* :num-toolbar-buts)) file)
        (print `(setf *num-toolbar-buts-shown-at-startup*  ,(send *toolbar* :num-icons-shown)) file)
        (print `(setf *nmobs* ,*nmobs*) file)
        (print `(setf *nplugins* ,*nplugins*) file)
        (print `(setf *nanalys* ,(+ *nplugins* *nmobs*)) file)
        (print `(setf *nitems* ,*nitems*) file)
        (print `(setf *nbutts* ,*nbutts*) file)
        (print `(setf *num-toolbar-buts-shown-at-startup* ,*num-toolbar-buts-shown-at-startup*) file)
        (print `(setf *button-names* ',*button-names*) file)
        (print `(setf *analysis-menu-items* ',*analysis-menu-items*) file)
        )))
    (setq *breakenable* oldbreak)
    (close file)
    (when *file-verbose* (format t "~a~%" (strcat "; saving  " *prefs-path* filename)))
    ))

(defun save-workmap-settings (&optional make-distribution filename)
  (unless filename (setf filename "workmap.lsp"))
  (let ((oldbreak *breakenable*)
        (file (open (strcat *prefs-dir-name* filename) :direction :output)))
    (setq *breakenable* nil)
    (unwind-protect
     (cond 
       (make-distribution
        (print `(send *workmap* :show-icon-ears? t) file)
        (print `(send *workmap* :new-icon-style? t) file)
        (print `(send *workmap* :short-icon-titles t) file)
        (print `(send *workmap* :zig-zag nil) file)
        (print `(send *workmap* :show-extensions? t) file)
        (print `(send *toolbar* :enable-soft-buttons nil) file)
        (print `(send *toolbar* :soft-button-titles ',*initial-button-names*) file)
        (print `(send *vista*   :previous-plugins ',*initial-button-names*) file)
        (print `(send *vista*   :analysis-menu-item-titles ',*initial-analysis-menu-items*) file)
        (print `(send *workmap* :num-toolbar-buts ,*initial-nmobs* ) file)
        (print `(setf *num-toolbar-buts-shown-at-startup*  ,*initial-nmobs* ) file)
        )
       (t
        (print `(send *workmap* :show-icon-ears? ,(send *workmap* :show-icon-ears?)) file)
        (print `(send *workmap* :new-icon-style? ,(send *workmap* :new-icon-style?)) file)
        (print `(send *workmap* :short-icon-titles ,(send *workmap* :short-icon-titles)) file)
        (print `(send *workmap* :zig-zag ,(send *workmap* :zig-zag)) file)
        (print `(send *workmap* :show-extensions? ,(send *workmap* :show-extensions?)) file)
        (print `(send *toolbar* :enable-soft-buttons ,(send *toolbar* :enable-soft-buttons)) file)
        (print `(send *toolbar* :soft-button-titles ',(send *toolbar* :soft-button-titles)) file)
        (print `(send *vista*   :previous-plugins ',(send *vista* :previous-plugins)) file)
        (print `(send *vista*   :analysis-menu-item-titles ',(send *vista* :analysis-menu-item-titles)) file)
        (print `(send *workmap* :num-toolbar-buts ,(send *workmap* :num-toolbar-buts)) file)
        (print `(setf *num-toolbar-buts-shown-at-startup*  ,(send *toolbar* :num-icons-shown)) file)
        ))
     (print `(send *workmap* :icon-title-color 'white) file)
     )
    (setq *breakenable* oldbreak)
    (close file)
    (when *file-verbose* (format t "~a~%" (strcat "; saving  " *prefs-path* filename)))
    ))

#|
 | DESKTOP FILE
 |
 | write-desktop-file, save-desktop-settings
 |
 |#

(defun update-desktop-sizeloc-info ()
  (when (and (boundp '*vista*) *vista*
             (boundp '*desktop-container* ) *desktop-container* )
        (send *vista* :desktop-size (send *desktop-container* :size))
        (send *vista* :desktop-location (send *desktop-container* :location))
        (setf *desktop-loc-size* 
              (combine (send *vista* :desktop-location) (send *vista* :desktop-size)))
        ))
  
  
(defun write-desktop-file (&optional desktop-only) 
    (save-desktop-file desktop-only))

(defun save-desktop-settings (&optional desktop-only filename)
  (unless filename (setf filename "desktop.lsp"))
  (let ((oldbreak *breakenable*)
        (file (open (strcat *prefs-dir-name* filename) :direction :output)))
    (send *vista* :desktop-size (send *desktop-container* :size))
    (send *vista* :desktop-location (send *desktop-container* :location))
    (setq *breakenable* nil)
    (unwind-protect
      (format file "(apply #'send *desktop-container* :size '~a)~%"
              (send *desktop-container* :size))
      (print `(apply #'send *desktop-container* :location 
             ',(send *desktop-container* :location)) file)
      (print `(setf *num-listener-lines* ,*num-listener-lines*) file)
     (format file   "(setf *layout-type* ~d)~%" *layout-type*)
     (format file   "(setf *color-mode* ~d)~%" *color-mode*) 
     (format file   "(setf *desktop-loc-size* '~d)~%" *desktop-loc-size*)
     (format file   "(setf *desktop-start-loc-size* '~d)~%" *desktop-start-loc-size*)
     (format file   "(setf *long-varobs* '~d)~%" *long-varobs*)
     (format file   "(setf *seven-values* '~d)~%" *seven-values*)
     (format file   "(send *vista* :save-desktop t)~%" )
     (format file   "(send *vista* :normalsize  ~d )~%" 
                     (send *vista* :normalsize))
     (format file   "(send *vista* :full-screen ~d )~%" 
                     (send *vista* :full-screen))

     (format file   "(send *vista* :desktop-size (list ~d ~d))~%" 
             (first  (send *vista* :desktop-size)) 
             (second (send *vista* :desktop-size)))
     (format file   "(send *vista* :desktop-location (list ~d ~d))~%" 
             (first  (send *vista* :desktop-location)) 
             (second (send *vista* :desktop-location)))
     (format file   "(send *vista* :workmap-size (list ~d ~d))~%" 
             (first  (send *vista* :workmap-size)) 
             (second (send *vista* :workmap-size)))
     (format file   "(send *vista* :datasheet-sizes (list ~d ~d))~%" 
             (first  (send *vista* :datasheet-sizes)) 
             (second (send *vista* :datasheet-sizes)))
     (format file   "(send *vista* :spreadplot-sizes (list ~d ~d))~%" 
             (first  (send *vista* :spreadplot-sizes))
             (second (send *vista* :spreadplot-sizes)))
     (format file   "(send *vista* :workmap-location (list ~d ~d))~%" 
             (first  (send *vista* :workmap-location)) 
             (second (send *vista* :workmap-location)))
     (format file   "(send *vista* :datasheet-location (list ~d ~d))~%" 
             (first  (send *vista* :datasheet-location)) 
             (second (send *vista* :datasheet-location)))
     (format file   "(send *vista* :workmap-proportion ~d)~%" 
                     (send *vista* :workmap-proportion))
     (format file   "(send *workmap* :size ~d ~d)~%" 
             (first  (send *workmap* :size))
             (second (send *workmap* :size)))
     (format file   "(send *workmap* :location ~d ~d)~%" 
             (first  (send *workmap* :location))
             (second (send *workmap* :location)))
    ; (format file   "(send *workmap* :new-icon-style? ~d)~%"
    ;                 (send *workmap* :new-icon-style?))
     (format file   "(send *vista* :background-color ~d)~%"
                     (send *vista* :background-color))
     (format file   "(send *workmap* :use-color t)")
   ;  (format file   "(when *datasheet* (apply #'send *datasheet* :size '~d))~%"
   ;                  (send *datasheet* :size))
     (print `(when *datasheet* (apply #'send *datasheet* :size '(500 250))) file)
     (setq *breakenable* oldbreak)
     (close file)
     (when *file-verbose* (format t "~a~%" (strcat "; saving  " *prefs-path* filename)))
     (unless desktop-only (send *vista* :save-prefload))
     )))
